bitkeeper revision 1.1236.1.25 (421f4d3f1OCTsnYVCTM2mhwvFDIGvA)
authormaf46@burn.cl.cam.ac.uk <maf46@burn.cl.cam.ac.uk>
Fri, 25 Feb 2005 16:07:27 +0000 (16:07 +0000)
committermaf46@burn.cl.cam.ac.uk <maf46@burn.cl.cam.ac.uk>
Fri, 25 Feb 2005 16:07:27 +0000 (16:07 +0000)
alloc_monitor_pagetable/update_pagetable cleanup.

update_pagetable() is now the only code that (ever) sets
arch.monitor_table.  update_pagetable() is also now smart
enough to deal with VMX guests while their paging is still
disabled.

Signed-off-by: michael.fetterman@cl.cam.ac.uk
xen/arch/x86/domain.c
xen/include/asm-x86/shadow.h
xen/include/xen/domain.h

index d3f2076cbe46378b8723e874ba0c509c572d6187..f2b46e8c07f387b8899787c0f0c47c135ba1594b 100644 (file)
@@ -295,7 +295,7 @@ void arch_vmx_do_launch(struct exec_domain *ed)
     reset_stack_and_jump(vmx_asm_do_launch);
 }
 
-static void alloc_monitor_pagetable(struct exec_domain *ed)
+unsigned long alloc_monitor_pagetable(struct exec_domain *ed)
 {
     unsigned long mmfn;
     l2_pgentry_t *mpl2e;
@@ -319,12 +319,13 @@ static void alloc_monitor_pagetable(struct exec_domain *ed)
         mk_l2_pgentry((__pa(d->arch.mm_perdomain_pt) & PAGE_MASK) 
                       | __PAGE_HYPERVISOR);
 
-    ed->arch.monitor_table = mk_pagetable(mmfn << PAGE_SHIFT);
     ed->arch.monitor_vtable = mpl2e;
 
     // map the phys_to_machine map into the Read-Only MPT space for this domain
     mpl2e[l2_table_offset(RO_MPT_VIRT_START)] =
         mk_l2_pgentry(pagetable_val(ed->arch.phys_table) | __PAGE_HYPERVISOR);
+
+    return mmfn;
 }
 
 /*
@@ -408,13 +409,7 @@ static int vmx_final_setup_guest(struct exec_domain *ed,
         shadow_mode_enable(ed->domain, SHM_enable|SHM_translate|SHM_external);
     }
 
-    /* We don't call update_pagetables() as we actively want fields such as 
-     * the linear_pg_table to be inaccessible so that we bail out early of 
-     * shadow_fault() in case the vmx guest tries illegal accesses with
-     * paging turned off. 
-     */
-    //update_pagetables(ed);     /* this assigns shadow_pagetable */
-    alloc_monitor_pagetable(ed); /* this assigns monitor_pagetable */
+    update_pagetables(ed);
 
     return 0;
 
index c02079fa8994722dff0c1733ee7966f339936567..670394ce60ce42764bd75438da9bca297d8dcf7a 100644 (file)
@@ -781,13 +781,27 @@ static inline void __update_pagetables(struct exec_domain *ed)
 static inline void update_pagetables(struct exec_domain *ed)
 {
     struct domain *d = ed->domain;
+    int paging_enabled =
+#ifdef CONFIG_VMX
+        !VMX_DOMAIN(ed) ||
+        test_bit(VMX_CPU_STATE_PG_ENABLED, &ed->arch.arch_vmx.cpu_state);
+#else
+        1;
+#endif
 
-    if ( unlikely(shadow_mode_enabled(d)) )
+    /*
+     * We don't call __update_pagetables() when vmx guest paging is
+     * disabled as we want the linear_pg_table to be inaccessible so that
+     * we bail out early of shadow_fault() if the vmx guest tries illegal
+     * accesses while it thinks paging is turned off.
+     */
+    if ( unlikely(shadow_mode_enabled(d)) && paging_enabled )
     {
         shadow_lock(d);
         __update_pagetables(ed);
         shadow_unlock(d);
     }
+
     if ( !shadow_mode_external(d) )
     {
 #ifdef __x86_64__
@@ -800,6 +814,15 @@ static inline void update_pagetables(struct exec_domain *ed)
         else
             ed->arch.monitor_table = ed->arch.guest_table;
     }
+    else
+    {
+        // External page tables...
+        // Allocate a monitor page table if we don't already have one.
+        //
+        if ( unlikely(!pagetable_val(ed->arch.monitor_table)) )
+            ed->arch.monitor_table =
+                mk_pagetable(alloc_monitor_pagetable(ed) << PAGE_SHIFT);
+    }
 }
 
 #if SHADOW_DEBUG
index 15db59d73d929d7f408748592a1883136437f46c..8db16e2512402ca3fceb370239f42e248c7d62f7 100644 (file)
@@ -27,4 +27,6 @@ extern void domain_relinquish_memory(struct domain *d);
 
 extern void dump_pageframe_info(struct domain *d);
 
+extern unsigned long alloc_monitor_pagetable(struct exec_domain *ed);
+
 #endif /* __XEN_DOMAIN_H__ */